#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <limits.h>
#include <dirent.h>
#include <sys/time.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <pwd.h>

#include "data_type.h"
#include "cube.h"
#include "cube_define.h"
#include "cube_record.h"

#include "shell_list.h"
#include "script_run.h"

#define MAX_LINE_LEN 1024

static unsigned char Buf[DIGEST_SIZE*32];

int script_run_init(void * sub_proc,void * para)
{
    int ret;

    return 0;
}

int script_run_start(void * sub_proc,void * para)
{
    int ret = 0, len = 0, i = 0, j = 0;
    int rc = 0;

    int type,subtype;	
	BYTE local_uuid[DIGEST_SIZE];	
    ret=proc_share_data_getvalue("uuid",local_uuid);
	if(ret<0)
		return ret;
    void * recv_msg;

    while(1)
    {
        usleep(time_val.tv_usec);

		ret=ex_module_recvmsg(sub_proc,&recv_msg);
		if(ret<0)
			continue;
		if(recv_msg==NULL)
			continue;
		type=message_get_type(recv_msg);
		subtype=message_get_subtype(recv_msg);
		if(!memdb_find_recordtype(type,subtype))
		{
			printf("message format (%d %d) is not registered!\n",
			message_get_type(recv_msg),message_get_subtype(recv_msg));
			continue;
		}
		if((type==TYPE(GENERAL_RETURN))&&(subtype==SUBTYPE(GENERAL_RETURN,STRING)))
		{
			ret=proc_script_run(sub_proc,recv_msg);
		}
	}
    return 0;
}

int proc_script_run(void * sub_proc,void * recv_msg)
{
    int ret;
    int i=0;
    void * send_msg;
    RECORD(GENERAL_RETURN,STRING) * shell_notice;

    char policy_type[DIGEST_SIZE];
    char policy_path[DIGEST_SIZE*4];

    ret = message_get_record(recv_msg,&shell_notice,0);
    if(ret<0)
        return ret;
    RECORD(SHELL_LIST,SCRIPT) * shell_script;

    DB_RECORD * db_record;

    db_record=memdb_find_first(TYPE_PAIR(SHELL_LIST,SCRIPT),"match_name",shell_notice->return_value);
    if(db_record == NULL)
        return -EINVAL;

    shell_script = db_record->record;

    if(shell_script == NULL)
        return -EINVAL;

    pid_t fpid; //fpid表示fork函数返回的值  
    int count=0;  
    fpid=fork();   
    if (fpid < 0) 
    {
          print_cubeerr("error in fork!");  
          return -EINVAL;
    }
    if (fpid == 0) {  
        struct passwd * passdata;
	int status;
        status = system(shell_script->script);
	if (-1 == status)
        {
          print_cubeerr("proc_script_run: system run %s error!",shell_script->script);
          exit(-EINVAL);
        }
        else
        {
            if (WIFEXITED(status))
            {
               if (0 == WEXITSTATUS(status))
               {
          	  print_cubeaudit("proc_script_run: system run %s succeed!",shell_script->script);
                  exit(0);
               }
               print_cubeerr("proc_script_run: run shell script %s fail, script exit code: %d\n", 
			shell_script->script,WEXITSTATUS(status));
              exit(-EINVAL);
            }
             print_cubeerr("proc_script_run: shell script %s exit fail, script exit code: %d\n", 
			shell_script->script,WEXITSTATUS(status));
             exit(-EINVAL);
        }
        exit(0);
    }  
    
    if(shell_script->next_match !=NULL)
    {
        if(shell_script->next_match[0]==0)
            return 0;

        usleep(shell_script->delay);
        shell_notice->return_value  = dup_str(shell_script->next_match,0);
        if(shell_script->next_match_name  != NULL)
            shell_notice->name  = dup_str(shell_script->next_match_name,0);
        send_msg=message_create(TYPE_PAIR(GENERAL_RETURN,STRING),NULL);
        if(send_msg==NULL)
            return -EINVAL;
        message_add_record(send_msg,shell_notice);
        ex_module_sendmsg(sub_proc,send_msg);
    }

    return 0; 
}
